/*     */ package com.zimbra.cs.octosync;
/*     */ 
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LogFactory;
/*     */ import java.io.DataInputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.nio.ByteBuffer;
/*     */ import java.nio.ByteOrder;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class BinaryPatchReader
/*     */   implements PatchReader
/*     */ {
/*  36 */   private static final Log log = LogFactory.getLog(BinaryPatchReader.class);
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final String HEADER_ID = "OPATCH";
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final short OPATCH_VERSION = 0;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final byte DATA_ID = 68;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final byte REF_ID = 82;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final int HASH_SIZE = 32;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private DataInputStream dis;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private long fileSize;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private PatchReader.RecordInfo nextRecordInfo;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private long numBytesLeftInCurrentDataRecord;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private long pos;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public BinaryPatchReader(InputStream is)
/*     */     throws IOException, BadPatchFormatException
/*     */   {
/* 115 */     this.dis = new DataInputStream(is);
/*     */     
/* 117 */     byte[] idBuf = new byte["OPATCH".length()];
/* 118 */     this.dis.readFully(idBuf);
/* 119 */     String id = new String(idBuf);
/*     */     
/* 121 */     if (!id.equals("OPATCH")) {
/* 122 */       throw new BadPatchFormatException("invalid patch header id: " + id);
/*     */     }
/*     */     
/* 125 */     this.pos += idBuf.length;
/*     */     
/* 127 */     short version = readShort();
/*     */     
/* 129 */     if (version != 0) {
/* 130 */       throw new BadPatchFormatException("unsupported version: " + version);
/*     */     }
/*     */     
/* 133 */     this.fileSize = readLong();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void resume(InputStream is) {}
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public long getFileSize()
/*     */   {
/* 163 */     return this.fileSize;
/*     */   }
/*     */   
/*     */ 
/*     */   public boolean hasMoreRecordInfos()
/*     */     throws IOException, BadPatchFormatException
/*     */   {
/* 170 */     if (this.nextRecordInfo != null) {
/* 171 */       return true;
/*     */     }
/*     */     
/*     */ 
/* 175 */     assert (this.numBytesLeftInCurrentDataRecord == 0L) : ("Not all bytes read from the current data record at " + this.pos);
/*     */     
/* 177 */     int value = this.dis.read();
/*     */     
/* 179 */     log.debug("Next record id at pos " + this.pos + ": " + value + " (char: " + (char)value + ")");
/*     */     
/* 181 */     if (value == -1) {
/* 182 */       close();
/* 183 */       return false;
/*     */     }
/*     */     
/* 186 */     this.pos += 1L;
/*     */     
/* 188 */     if (value == 68) {
/* 189 */       long len = readLong();
/*     */       
/* 191 */       if (len == 0L) {
/* 192 */         throw new BadPatchFormatException("zero length data record at position: " + (this.pos - 8L));
/*     */       }
/*     */       
/* 195 */       this.nextRecordInfo = new PatchReader.RecordInfo();
/* 196 */       this.nextRecordInfo.type = PatchReader.RecordType.DATA;
/* 197 */       this.nextRecordInfo.length = len;
/* 198 */     } else if (value == 82) {
/* 199 */       this.nextRecordInfo = new PatchReader.RecordInfo();
/* 200 */       this.nextRecordInfo.type = PatchReader.RecordType.REF;
/*     */     } else {
/* 202 */       throw new BadPatchFormatException("garbage in patch: " + value + " at position: " + this.pos);
/*     */     }
/*     */     
/* 205 */     return true;
/*     */   }
/*     */   
/*     */ 
/*     */   public PatchReader.RecordInfo getNextRecordInfo()
/*     */     throws IOException, BadPatchFormatException
/*     */   {
/* 212 */     assert (this.nextRecordInfo != null);
/* 213 */     return this.nextRecordInfo;
/*     */   }
/*     */   
/*     */ 
/*     */   public InputStream popData()
/*     */     throws IOException
/*     */   {
/* 220 */     assert (this.nextRecordInfo != null);
/* 221 */     assert (this.nextRecordInfo.type == PatchReader.RecordType.DATA);
/*     */     
/* 223 */     this.numBytesLeftInCurrentDataRecord = this.nextRecordInfo.length;
/* 224 */     this.nextRecordInfo = null;
/*     */     
/*     */ 
/* 227 */     new InputStream()
/*     */     {
/*     */ 
/*     */       public int read(byte[] b, int off, int len)
/*     */         throws IOException
/*     */       {
/* 233 */         if (BinaryPatchReader.this.numBytesLeftInCurrentDataRecord == 0L) {
/* 234 */           return -1;
/*     */         }
/*     */         
/* 237 */         int numRead = BinaryPatchReader.this.dis.read(b, off, (int)Math.min(len, BinaryPatchReader.this.numBytesLeftInCurrentDataRecord));
/*     */         
/*     */ 
/*     */ 
/* 241 */         if (numRead != -1) {
/* 242 */           BinaryPatchReader.access$022(BinaryPatchReader.this, numRead);
/* 243 */           BinaryPatchReader.access$214(BinaryPatchReader.this, numRead);
/*     */         }
/*     */         
/* 246 */         return numRead;
/*     */       }
/*     */       
/*     */ 
/*     */       public int read()
/*     */         throws IOException
/*     */       {
/* 253 */         if (BinaryPatchReader.this.numBytesLeftInCurrentDataRecord == 0L) {
/* 254 */           return -1;
/*     */         }
/*     */         
/* 257 */         int value = BinaryPatchReader.this.dis.read();
/*     */         
/* 259 */         if (value != -1) {
/* 260 */           BinaryPatchReader.access$006(BinaryPatchReader.this);
/* 261 */           BinaryPatchReader.access$204(BinaryPatchReader.this);
/*     */         }
/*     */         
/* 264 */         return value;
/*     */       }
/*     */       
/*     */ 
/*     */       public int available()
/*     */         throws IOException
/*     */       {
/* 271 */         return (int)Math.min(BinaryPatchReader.this.numBytesLeftInCurrentDataRecord, BinaryPatchReader.this.dis.available());
/*     */       }
/*     */       
/*     */       public long skip(long n)
/*     */         throws IOException
/*     */       {
/* 277 */         long toSkip = Math.min(BinaryPatchReader.this.numBytesLeftInCurrentDataRecord, n);
/* 278 */         long skipped = BinaryPatchReader.this.dis.skip(toSkip);
/*     */         
/* 280 */         BinaryPatchReader.access$022(BinaryPatchReader.this, skipped);
/* 281 */         BinaryPatchReader.access$214(BinaryPatchReader.this, skipped);
/*     */         
/* 283 */         return skipped;
/*     */       }
/*     */     };
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public PatchRef popRef()
/*     */     throws IOException, BadPatchFormatException, InvalidPatchReferenceException
/*     */   {
/* 293 */     log.debug("Reading REF at pos " + this.pos);
/*     */     
/* 295 */     assert (this.nextRecordInfo.type == PatchReader.RecordType.REF);
/*     */     
/* 297 */     this.nextRecordInfo = null;
/*     */     
/* 299 */     PatchRef patchRef = new PatchRef();
/*     */     
/* 301 */     patchRef.fileId = readInt();
/* 302 */     patchRef.fileVersion = readInt();
/* 303 */     patchRef.offset = readLong();
/* 304 */     patchRef.length = readInt();
/*     */     
/* 306 */     if (patchRef.length == 0) {
/* 307 */       throw new InvalidPatchReferenceException("zero length referenced at position: " + (this.pos - 4L));
/*     */     }
/*     */     
/* 310 */     patchRef.hashKey = new byte[32];
/* 311 */     this.dis.readFully(patchRef.hashKey);
/* 312 */     this.pos += patchRef.hashKey.length;
/*     */     
/* 314 */     return patchRef;
/*     */   }
/*     */   
/*     */   public void close() throws IOException
/*     */   {
/* 319 */     this.dis.close();
/*     */   }
/*     */   
/*     */   private ByteBuffer getByteBuffer(byte[] array)
/*     */   {
/* 324 */     return ByteBuffer.wrap(array).order(ByteOrder.LITTLE_ENDIAN);
/*     */   }
/*     */   
/*     */   private short readShort() throws IOException, BadPatchFormatException
/*     */   {
/* 329 */     byte[] buf = new byte[2];
/* 330 */     this.dis.readFully(buf);
/* 331 */     this.pos += buf.length;
/* 332 */     return getByteBuffer(buf).getShort();
/*     */   }
/*     */   
/*     */   private int readInt() throws IOException, BadPatchFormatException
/*     */   {
/* 337 */     byte[] buf = new byte[4];
/* 338 */     this.dis.readFully(buf);
/* 339 */     this.pos += buf.length;
/* 340 */     return getByteBuffer(buf).getInt();
/*     */   }
/*     */   
/*     */   private long readLong() throws IOException, BadPatchFormatException
/*     */   {
/* 345 */     byte[] buf = new byte[8];
/* 346 */     this.dis.readFully(buf);
/* 347 */     this.pos += buf.length;
/* 348 */     return getByteBuffer(buf).getLong();
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/octosync/BinaryPatchReader.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */